<?php

namespace iBrand\Shop\Backend\Http\Controllers;

use Encore\Admin\Facades\Admin as LaravelAdmin;
use Encore\Admin\Layout\Content;
use iBrand\Component\Goods\Models\Goods;
use iBrand\Component\Goods\Models\GoodsProduct;
use iBrand\Component\Goods\Models\Supplier;
use iBrand\Component\Goods\Repositories\GoodsProductRepository;
use iBrand\Component\Goods\Repositories\GoodsRepository;
use iBrand\Component\Purchase\Models\Purchase;
use iBrand\Component\Purchase\Models\StockRecord;
use iBrand\Component\Purchase\Repositories\PurchaseItemRepository;
use iBrand\Component\Purchase\Repositories\PurchaseRepository;
use iBrand\Component\Purchase\Repositories\StockRecordRepository;
use iBrand\Shop\Backend\Repository\O2oGoodsProductsRepository;
use iBrand\Shop\Backend\Repository\O2oGoodsRepository;
use iBrand\Shop\Backend\Service\CommonService;
use iBrand\Shop\Core\Models\ClerkAdminRelation;
use iBrand\Shop\Core\Models\O2oGoodsProducts;
use iBrand\Shop\Core\Service\WarehouseService;
use Illuminate\Http\Request;
use Validator;
use DB;

class PurchaseController extends Controller
{
    protected $purchaseRepository;
    protected $goodsRepository;
    protected $purchaseItemRepository;
    protected $goodsProductRepository;
    protected $stockRecordRepository;
    protected $o2oGoodsRepository;
    protected $o2oGoodsProductsRepository;
    protected $commonService;
    protected $warehouseService;

    public function __construct(PurchaseRepository $purchaseRepository,
                                GoodsRepository $goodsRepository,
                                PurchaseItemRepository $purchaseItemRepository,
                                GoodsProductRepository $goodsProductRepository,
                                StockRecordRepository $stockRecordRepository,
                                O2oGoodsRepository $o2oGoodsRepository,
                                O2oGoodsProductsRepository $o2oGoodsProductsRepository,
                                CommonService $commonService,
                                WarehouseService $warehouseService)
    {
        $this->purchaseRepository = $purchaseRepository;
        $this->goodsRepository = $goodsRepository;
        $this->purchaseItemRepository = $purchaseItemRepository;
        $this->goodsProductRepository = $goodsProductRepository;
        $this->stockRecordRepository = $stockRecordRepository;
        $this->o2oGoodsRepository = $o2oGoodsRepository;
        $this->o2oGoodsProductsRepository = $o2oGoodsProductsRepository;
        $this->commonService = $commonService;
        $this->warehouseService = $warehouseService;
    }

    public function index()
    {
        $condition = $this->searchCondition();

        $lists = $this->purchaseRepository->getPurchasePaginate($condition[0], $condition[1]);

        return LaravelAdmin::content(function (Content $content) use ($lists) {

            $content->header('采购单');

            $content->breadcrumb(
                ['text' => '采购管理', 'url' => 'warehouse/purchase', 'no-pjax' => 1],
                ['text' => '采购单', 'url' => '', 'no-pjax' => 1, 'left-menu-active' => '采购单']
            );

            $content->body(view('shop-backend::purchase.index', compact('lists')));
        });
    }

    private function searchCondition()
    {
        $where['shop_id'] = session('shop_id');
        $where['type'] = Purchase::TYPE_PURCHASE;
        $time = [];

        if (request('code')) {
            $where['code'] = ['like', '%' . request('code') . '%'];
        }

        if (!empty(request('etime')) && !empty(request('stime'))) {
            $where['created_at'] = ['<=', request('etime')];
            $time['created_at'] = ['>=', request('stime')];
        }

        if (!empty(request('etime'))) {
            $time['created_at'] = ['<=', request('etime')];
        }

        if (!empty(request('stime'))) {
            $time['created_at'] = ['>=', request('stime')];
        }

        return [$where, $time];
    }

    public function show()
    {
        $order_no = request('order_no');
        $purchase = $this->purchaseRepository->findWhere(['code' => $order_no])->first();

        return LaravelAdmin::content(function (Content $content) use ($purchase) {

            $content->header('查看采购详情');

            $content->breadcrumb(
                ['text' => '采购管理', 'url' => 'warehouse/purchase', 'no-pjax' => 1],
                ['text' => '采购单', 'url' => '', 'no-pjax' => 1, 'left-menu-active' => '采购单']
            );

            $content->body(view('shop-backend::purchase.show', compact('purchase')));
        });
    }

    public function create()
    {
        $suppliers = Supplier::where('status', 1)->get(['id', 'name', 'code'])->toArray();
        $specList = $this->commonService->getSpecList();
        $colors = $specList['colors'];
        $sizes = $specList['sizes'];
        $order_type = Purchase::TYPE_PURCHASE;
        $button_text = '采购';

        return LaravelAdmin::content(function (Content $content) use ($suppliers, $colors, $sizes, $order_type, $button_text) {

            $content->header('采购单');

            $content->breadcrumb(
                ['text' => '采购管理', 'url' => 'warehouse/purchase', 'no-pjax' => 1],
                ['text' => '采购单', 'url' => '', 'no-pjax' => 1, 'left-menu-active' => '采购单']
            );

            $content->body(view('shop-backend::purchase.create', compact('suppliers', 'sizes', 'colors', 'order_type', 'button_text')));
        });
    }

    public function store(Request $request)
    {
        $order = $request->input('order');
        $order = json_decode($order, true);
        $goods = $request->input('goods');
        $goods = json_decode($goods, true);

        if (empty($goods) || empty($order)) {
            return $this->ajaxJson(false, [], 500, '请选择商品');
        }

        $orderValidator = $this->validateOrder($order);
        if ($orderValidator->fails()) {

            return $this->ajaxJson(false, [], 500, $orderValidator->messages()->first());
        }

        $goodsValidator = $this->validateGoods($goods);
        if ($goodsValidator->fails()) {

            return $this->ajaxJson(false, [], 500, $goodsValidator->messages()->first());
        }

        $shop_id = session('shop_id');
        try {
            DB::beginTransaction();

            $clerk = ClerkAdminRelation::where('admin_id', auth('admin')->user()->id)->first();

            $prefix = 'JT';
            if ($order['order_type'] == Purchase::TYPE_REJECT) {
                $prefix = 'JTR';
            }

            $purchaseData = [
                'shop_id' => $shop_id,
                'code' => $prefix . date('YmdHis') . mt_rand(10000000, 99999999),
                'clerk_id' => $clerk ? $clerk->clerk_id : 0,
                'type' => $order['order_type'],
                'remark' => $order['remark'],
                'quantity' => $order['quantity'],
                'total' => $order['trueTotalAmount'],
                'status' => Purchase::STATUS_DEFAULT,
            ];

            $purchase = $this->purchaseRepository->create($purchaseData);

            foreach ($goods as $good) {
                if ($good['currentSku']) {
                    $product = $this->goodsProductRepository->getProductBySku($good['currentSku']);
                    $item_id = $product->id;
                    $item_type = GoodsProduct::class;
                } else {
                    $item_id = $good['goods_id'];
                    $item_type = Goods::class;
                }

                $this->warehouseService->addPurchaseItem($purchase->id, $good, $item_id, $item_type);

                $this->warehouseService->addStockRecord($shop_id, $purchase->id, $good, $order['order_type'], $item_id, $item_type);

                $o2oGoods = $this->o2oGoodsRepository->findWhere(['status' => 1, 'goods_id' => $good['goods_id'], 'shop_id' => $shop_id])->first();
                if (!$o2oGoods) {
                    $o2oGoods = $this->o2oGoodsRepository->create([
                        'goods_id' => $good['goods_id'],
                        'shop_id' => $shop_id,
                        'price' => $good['price'],
                    ]);
                }

                $o2oGoodsId = $o2oGoods->id;

                $this->warehouseService->addO2oGoodsProduct($shop_id, $o2oGoodsId, $good['goods_id'], $good['quantity'],'Purchase', $order['order_type'], $item_id);

                if ($order['order_type'] == Purchase::TYPE_REJECT) {
                    $o2oGoods->reduceStock($good['quantity']);
                } else {
                    $o2oGoods->restoreStock($good['quantity']);
                }

            }

            DB::commit();

            return $this->ajaxJson();
        } catch (\Exception $exception) {
            DB::rollBack();
            \Log::info($exception->getTraceAsString());

            return $this->ajaxJson(false, '', 500, $exception->getMessage());
        }
    }


    public function validateOrder($order)
    {
        $rules = [
            'trueTotalAmount' => 'required|numeric|min:1',
            'totalAvailableRows' => 'required|integer|min:1',
            'quantity' => 'required|integer|min:1',
        ];

        $message = [
            "required" => ":attribute 不能为空",
            "integer" => ":attribute 必须是整数",
            "numeric" => ":attribute 必须是数字",
            "min" => ":attribute 必须大于0",
        ];

        $attributes = [
            'trueTotalAmount' => '采购总金额',
            'totalAvailableRows' => '商品',
            'quantity' => '商品采购数量',
        ];

        $validator = Validator::make($order, $rules, $message, $attributes);

        return $validator;
    }

    public function validateGoods($goods)
    {
        $rules = [
            '*.goods_name' => 'required',
            '*.goods_no' => 'required',
            '*.goods_id' => 'required',
            '*.currentSku' => 'required',
            '*.color' => 'required',
            '*.size' => 'required',
            '*.quantity' => 'required|integer|min:1',
            '*.price' => 'required|numeric|min:1',
            '*.truePrice' => 'required|numeric|min:1',
            '*.trueAmount' => 'required|numeric|min:1',
        ];

        $message = [
            "required" => ":attribute 不能为空",
            "integer" => ":attribute 必须是整数",
            "numeric" => ":attribute 必须是数字",
            "min" => ":attribute 必须大于0",
        ];

        $attributes = [
            '*.goods_name' => '商品名称',
            '*.goods_no' => '商品货号',
            '*.goods_id' => '商品id',
            '*.currentSku' => '商品sku',
            '*.quantity' => '采购数量',
            '*.price' => '采购单价',
            '*.truePrice' => '采购折后价',
            '*.trueAmount' => '总金额',
        ];

        $validator = Validator::make($goods, $rules, $message, $attributes);

        return $validator;
    }
}